package com.roy;

import com.roy.demo.pojo.Evection;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

/**
 * @author :duyus
 * @description: 分支： 所有外出顺序流的条件都会被解析，结果为true的顺序流会以并行方式继续
 * 执行， 会为每个顺序流创建一个分支。
 * @description: 汇聚： 所有并行分支到达包含网关，会进入等待状态， 直到每个包含流程token的
 * 进入顺序流的分支都到达。 这是与并行网关的最大不同。换句话说，包含网关只会
 * 等待被选中执行了的进入顺序流。 在汇聚之后，流程会穿过包含网关继续执行。
 *
 * @description: 包容网关（Inclusive Gateway）用法及特点：
 * 1. 包容网关可以根据条件选择一条或多条分支同时执行，支持多分支并发。
 * 2. 进入包容网关时，会判断每条分支的条件，所有满足条件的分支都会被激活。
 * 3. 如果所有条件都不满足，可以设置默认分支，否则流程会异常结束。
 * 4. 包容网关的汇聚点会等待所有被激活的分支都到达后，才会继续向下执行。
 * 5. 适用于部分并行、部分互斥的业务场景，灵活性高。
 * 6. 既支持并发也支持条件判断，兼具并行网关和排他网关的部分特性。
 * 7. 如果只满足一个条件，则表现类似排他网关；如果满足多个条件，则多个分支并发。
 */
public class ActivitiGatewayInclusive {
    /**
     * 部署流程定义
     */
    @Test
    public void testDeployment(){
//        1、创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();
//        3、使用RepositoryService进行部署
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("bpmn/evection-inclusive.bpmn") // 添加bpmn资源
//                .addClasspathResource("bpmn/evection.png")  // 添加png资源
                .name("出差申请流程-包含网关")
                .deploy();
//        4、输出部署信息
        System.out.println("流程部署id：" + deployment.getId());
        System.out.println("流程部署名称：" + deployment.getName());
    }

    /**
     * 启动流程实例,设置流程变量的值
     */
    @Test
    public void startProcess(){
//        获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        获取RunTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
//        流程定义key
        String key = "inclusive";
//       创建变量集合
        Map<String, Object> map = new HashMap<>();
//        创建出差pojo对象
        Evection evection = new Evection();
//        设置出差天数
        evection.setNum(4d);
//      定义流程变量，把出差pojo对象放入map
        map.put("evection",evection);
//        启动流程实例，并设置流程变量的值（把map传入）
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey(key, map);
//      输出
        System.out.println("流程实例名称="+processInstance.getName());
        System.out.println("流程定义id=="+processInstance.getProcessDefinitionId());
    }

    @Test
    public void completTask(){
//        流程定义的Key
        String key = "inclusive";
//        任务负责人
        String assingee = "jack";
        //        获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        获取taskservice
        TaskService taskService = processEngine.getTaskService();
//        查询任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee(assingee)
                .singleResult();
        if(task != null){
            //     根据任务id来   完成任务
            taskService.complete(task.getId());
        }

    }
}
